from docx.shared import Pt, Cm
from docx.enum.text import *
import os
from docx import Document
from docx.oxml import OxmlElement, CT_P  # OxmlElement 用于创建元素, CT_P 是段落的 XML 类型
from docx.oxml.ns import qn  # qn 用于处理命名空间
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox,scrolledtext


# 删除段落
def delete_paragraph(paragraph):
    p = paragraph._element
    p.getparent().remove(p)
    # p._p = p._element = None
    paragraph._p = paragraph._element = None


# 判断是否为落款格式
def LuoKuan(str):
    for i in str:
        if i in punc:
            return False
    if ((str[0] in num) and (str[-1] == "日") and (len(str) <= 12)) or (
            (str[0] in cn_num) and (str[-1] == "日") and (len(str) <= 12)):
        return True
    else:
        return False


# 设置页面高度和页边距
def setMargin(docx):
    section = docx.sections[0]
    section.page_height = Cm(29.7)
    section.page_width = Cm(21.0)
    section.left_margin = Cm(2.8)
    section.right_margin = Cm(2.6)
    section.top_margin = Cm(3.7)
    section.bottom_margin = Cm(3.5)


# 判断是否为一级标题格式（如：一、xxx）
def GradeOneTitle(str):
    if ((str[0] in cn_num) and (str[1] == "、")) or ((str[0] in cn_num) and (str[1] in cn_num) and (str[2] == "、")):
        return True
    else:
        return False


# 判断是否为二级标题格式（如：（一）xxx）
def GradeTwoTitle(str):
    if ((str[0] == "（") and (str[1] in cn_num) and (str[2] == "）")) or (
            (str[0] == "（") and (str[1] in cn_num) and (str[2] in cn_num) and (str[3] == "）")):
        return True
    else:
        return False


# 判断是否为三级标题格式（如：1.xxx）
def GradeThreeTitle(str):
    if ((str[0] in num) and (str[1] in punc)) or ((str[0] in num) and (str[1] in num) and (str[2] in punc)):
        return True
    else:
        return False


# 判断是否为四级标题格式（如：（1）xxx）
def GradeFourTitle(str):
    if ((str[0] == "（") and (str[1] in num) and (str[2] == "）")) or (
            (str[0] == "（") and (str[1] in num) and (str[2] in num) and (str[3] == "）")):
        return True
    else:
        return False


# 判断是否为五级标题格式（如：一是XXX）
def GradeFiveTitle(str):
    if ((str[0] in cn_num) and (str[1] in must)) or ((str[0] in cn_num) and (str[1] in cn_num) and (str[1] in must)):
        return True
    else:
        return False


# 判断文件是否被另一个进程锁定。
def is_file_locked(filepath):
    """
    尝试通过以读写模式打开文件来粗略判断文件是否被另一个进程锁定。

    工作原理:
    1. 如果文件不存在，则肯定未被占用，返回 False。
    2. 如果文件存在，尝试以 'r+' (读写) 模式打开它。
       - 成功打开并立即关闭：表明当前进程可以访问，很可能未被独占锁定，返回 False。
       - 抛出 PermissionError：表明操作系统拒绝访问，很可能文件正被另一个进程（如Word）独占打开，返回 True。
       - 抛出其他 OSError：表明可能存在其他I/O问题（如路径错误、磁盘错误等），出于谨慎考虑，也返回 True。

    注意:
    - 这种方法并非绝对可靠，但在大多数常见场景下有效。
    - 它无法区分文件是被占用还是当前用户没有权限访问。

    参数:
        filepath (str): 要检查的文件的完整路径。

    返回:
        bool: 如果文件可能被锁定则返回 True，否则返回 False。
    """
    # 1. 检查文件是否存在
    if not os.path.exists(filepath):
        # 文件不存在，肯定没被占用
        return False

    try:
        # 2. 尝试以读写模式 ('r+') 打开文件。
        #    这不需要读取或写入内容，只是测试能否获得访问权限。
        #    'with' 语句确保文件会立即被关闭。
        with open(filepath, 'r+'):
            pass  # 立即关闭文件
        # 如果成功执行到这里，说明文件可以被访问，可能未被锁定。
        return False

    except PermissionError:
        # PermissionError 是最明确的指示，表明文件很可能被另一个进程独占锁定了。
        return True

    except OSError:
        # 捕获其他可能的 OSError (如 IOError, FileNotFoundError [理论上不会因为上面检查了],
        # IsADirectoryError 等)。出于健壮性考虑，将这些情况也视为文件可能无法访问（可能被占用或有其他问题）。
        return True

    except Exception:
        # 捕获任何其他未预期的异常，也视为可能有问题。
        return True


def THandYXSJ(paragraph):
    paragraph.text = paragraph.text.replace(",", "，")
    paragraph.text = paragraph.text.replace(";", "；")
    paragraph.text = paragraph.text.replace(":", "：")
    paragraph.text = paragraph.text.replace("!", "！")
    paragraph.text = paragraph.text.replace("?", "？")
    paragraph.text = paragraph.text.replace("(", "（")
    paragraph.text = paragraph.text.replace(")", "）")
    paragraph.text = paragraph.text.replace(" ", "")
    paragraph.text = paragraph.text.replace("\t", "")
    paragraph.text = paragraph.text.replace("\n", "")
    # --- 直接操作底层 XML 来清除各种缩进 ---
    # 使用 python-docx 的 oxml 层直接访问和修改段落的 XML 结构
    # 这是一种更底层、更彻底的清除缩进的方式
    # paragraph.paragraph_format.element 获取段落的 XML 元素
    paragraph.paragraph_format.left_indent = 0  # 预先对缩进赋值, 防止对象为空报错
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:firstLineChars"), '0')  # 并去除缩进
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:firstLine"), '0')
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:leftChars"), '0')
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:left"), '0')
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:rightChars"), '0')
    paragraph.paragraph_format.element.pPr.ind.set(qn("w:right"), '0')


def add_page_number(docx):
    """
    为文档的所有节添加页码。
    页码位于页面底端，对齐方式为居中。
    页码字体设置为 Times New Roman，字号 10.5 磅。
    此函数会清空页脚中已有的所有内容，并替换为新的居中页码。
    """
    # 遍历文档中的所有节 (Section)
    for section in docx.sections:
        # 获取当前节的页脚 (Footer)
        footer = section.footer

        # --- 关键修改：清空页脚中的所有现有内容 ---
        # 遍历页脚中的所有段落，并移除它们的底层 XML 元素
        for paragraph in footer.paragraphs:
            # 获取段落对应的底层 XML 元素
            p_element = paragraph._element
            # 从父元素（页脚）中移除该段落元素
            p_element.getparent().remove(p_element)

        # --- 添加新的页码段落 ---
        # 现在页脚是空的，添加一个新段落
        new_paragraph = footer.add_paragraph()

        # 设置新段落的对齐方式为居中
        new_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

        # --- 添加页码字段 {PAGE} 到新段落 ---
        # 1. 创建一个 run 来包含页码
        run_page_num = new_paragraph.add_run()

        # 2. 设置该 run 的字体和字号
        run_page_num.font.name = 'Times New Roman'
        run_page_num.font.size = Pt(10.5)  # 设置字号为 10.5 磅

        # 3. 手动添加页码字段 {PAGE} 的 XML 结构
        # 3.1 创建字段开始标记
        fldChar1 = OxmlElement('w:fldChar')
        fldChar1.set(qn('w:fldCharType'), 'begin')

        # 3.2 创建包含指令的文本
        instrText = OxmlElement('w:instrText')
        instrText.text = "PAGE"

        # 3.3 创建字段结束标记
        fldChar2 = OxmlElement('w:fldChar')
        fldChar2.set(qn('w:fldCharType'), 'end')

        # 3.4 将这些 XML 元素添加到 run 的底层 XML 中
        run_page_num._element.append(fldChar1)
        run_page_num._element.append(instrText)
        run_page_num._element.append(fldChar2)


# 检测并移除段落的自动编号或项目符号。
def remove_autonumber(paragraph):
    """
    检测并移除段落的自动编号或项目符号。

    Args:
        paragraph (docx.text.paragraph.Paragraph): 要处理的段落对象。
    """
    # 获取段落的底层 XML 元素
    p_element = paragraph._element

    # 查找段落属性 <w:pPr> 元素
    p_pr = p_element.get_or_add_pPr()

    # 查找编号定义引用 <w:numPr> 元素
    num_pr = p_pr.find(qn('w:numPr'))

    if num_pr is not None:
        # 找到了编号，移除整个 <w:numPr> 元素
        p_pr.remove(num_pr)
        print(f"已移除段落的自动编号。")
    else:
        print(f"段落无自动编号，无需处理。")


def set_chinese_font(run, font_name, size=None):
    """设置中文字体兼容西文和中文"""
    run.font.name = font_name
    run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
    if size:
        run.font.size = size


def luokuan(docx):
    """
    默认最后两段为落款：
    - 倒数第二行：单位名称
    - 最后一行：日期
    使用左缩进控制单位名称相对于日期居中。
    """
    if len(docx.paragraphs) < 2:
        print("段落不足，无法处理落款。")
        return False

    date_para = docx.paragraphs[-1]
    unit_para = docx.paragraphs[-2]

    date_text = date_para.text.strip()
    unit_text = unit_para.text.strip()

    print(f"格式化落款：单位='{unit_text}', 日期='{date_text}'")

    # =============================
    # 1. 格式化日期行（右对齐 + 右缩进）
    # =============================
    # 清空原有内容
    for run in list(date_para.runs):
        run.text = ''

    fmt = date_para.paragraph_format
    fmt.alignment = WD_ALIGN_PARAGRAPH.RIGHT
    fmt.right_indent = Pt(96)  # 96 磅 ≈ 8 字符宽度

    date_run = date_para.add_run(date_text)
    # 可选字体设置
    set_chinese_font(date_run, '方正仿宋简体', Pt(16))

    # =============================
    # 2. 格式化单位名称行（通过左缩进居中）
    # =============================
    # 清空原有内容
    for run in list(unit_para.runs):
        run.text = ''

    # --- 计算左缩进值 ---
    # 假设 A4 纸：21cm 宽
    # 左页边距：2.8cm，右页边距：2.6cm
    # 右缩进：96 Pt ≈ 3.39 cm
    # 所以文本区宽度 = 21 - 2.8 - 2.6 - 3.39 = 12.61 cm

    # 单位名称居中，所以左缩进 = 左边距 + (文本区宽度 - 单位文本宽度) / 2

    # 但我们不知道单位文本宽度（字符宽度不同），所以用**字符数估算**
    # 仿宋三号字，1字符 ≈ 0.42 cm（经验值）
    char_width_cm = 0.42
    unit_text_width_cm = len(unit_text) * char_width_cm

    # 文本区宽度（cm）
    text_area_width_cm = 21 - 2.8 - 2.6 - (96 * 2.54 / 72)  # 96 Pt → cm
    indent_left_cm = 3 + (text_area_width_cm - unit_text_width_cm) / 2

    # 设置左缩进
    unit_para.paragraph_format.left_indent = Cm(indent_left_cm)
    unit_para.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT  # 左对齐

    # 添加单位名称
    unit_run = unit_para.add_run(unit_text)
    # 可选字体设置
    set_chinese_font(unit_run, '方正仿宋简体', Pt(16))

    print("落款格式化完成（使用左缩进）。")
    return True


# 将包含英文字母或数字的 run 的西文字体设为 'Times New Roman'，
def ZST(docx):
    """
    将包含英文字母或数字的 run 的西文字体设为 'Times New Roman'，
    不改变其原有中文字体（如方正仿宋简体），避免中文变英文字体。
    """
    for para in docx.paragraphs:
        for run in para.runs:
            text = run.text.strip()
            if not text:
                continue

            # 判断是否包含英文字母或数字
            has_latin = any(char.isalpha() and char.isascii() for char in text) or \
                        any(char.isdigit() for char in text)

            if has_latin:
                r = run._element  # 获取底层 <w:r> 元素
                rPr = r.get_or_add_rPr()  # 获取或创建 <w:rPr>

                # --- 设置西文字体：Times New Roman ---
                rFonts = rPr.find(qn('w:rFonts'))
                if rFonts is None:
                    rFonts = OxmlElement('w:rFonts')
                    rPr.append(rFonts)

                # ✅ 只设置西文字体（ascii），不影响中文字体
                rFonts.set(qn('w:ascii'), 'Times New Roman')
                rFonts.set(qn('w:hAnsi'), 'Times New Roman')  # 用于中文环境下的英文
                rFonts.set(qn('w:cs'), 'Times New Roman')  # 复杂脚本

                print(f"已设置西文字体: '{text}' -> Times New Roman (中文不变)")


def print_format_guide():
    # 设置中文对齐宽度（中文字符占2英文字符位，这里用英文空格填充）
    # 使用全角空格或控制英文空格数量来对齐
    print("\n" + "=" * 60)
    print("              正 文 格 式 规 范")
    print("=" * 60)

    # 逐条输出，用缩进和换行提升可读性
    print("1. 页边距：")
    print("   上 3.7 厘米，下 3.5 厘米，")
    print("   左 2.8 厘米，右 2.6 厘米。")
    print("   ✅ 已搞定\n")

    print("2. 大标题：")
    print("   字体：方正小标宋简体")
    print("   字号：二号")
    print("   对齐：居中")
    print("   特殊：大标题上空 1 行")
    print("   ✅ 已搞定\n")

    print("3. 正文字体：")
    print("   正文：方正仿宋简体")
    print("   一级标题：方正黑体简体，格式为“一、******”，单行不加句号")
    print("   二级标题：方正楷体简体（可加粗），格式为“（一）******”")
    print("   三级标题：方正仿宋简体加粗，格式为“一是******”，一般加句号")
    print("   所有标题均为三号字体")
    print("   ✅ 已搞定\n")

    print("4. 段落格式：")
    print("   对齐方式：两端对齐")
    print("   特殊格式：首行缩进 2 字符")
    print("   段前 / 段后：0 行")
    print("   行距：固定值 28 磅")
    print("   ✅ 已搞定\n")

    print("5. 页码：")
    print("   位置：页面底端")
    print("   对齐：居中")
    print("   ✅ 已搞定\n")

    print("6. 落款：")
    print("   日期：领导签批日期")
    print("   位置：最后一个字距离右侧 8 个字符（约 96 磅）")
    print("   单位名称：在日期上一行，较日期居中")
    print("   ✅ 已搞定\n")

    print("7. 字体统一：")
    print("   全文最后用 Times New Roman 字体")
    print("   刷一遍字母、数字、标点符号等")
    print("   ✅ 已搞定\n")

    print("🎉 所有格式项均已处理完成！")
    print("=" * 60 + "\n")


# === 1. 创建一个窗口，用来显示格式规范 ===
def show_format_guide():
    guide_window = tk.Toplevel()
    guide_window.title("正文格式规范")
    guide_window.geometry("500x400")  # 设置窗口大小
    guide_window.resizable(False, False)  # 禁止缩放

    # 创建一个可滚动的文本框
    text_area = scrolledtext.ScrolledText(guide_window, wrap=tk.WORD, font=("微软雅黑", 10))
    text_area.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

    # 格式规范内容
    format_text = """
============================================================
              正 文 格 式 规 范
============================================================
1. 页边距：
   上 3.7 厘米，下 3.5 厘米，
   左 2.8 厘米，右 2.6 厘米。
   ✅ 已搞定

2. 大标题：
   字体：方正小标宋简体
   字号：二号
   对齐：居中
   特殊：大标题上空 1 行
   ✅ 已搞定

3. 正文字体：
   正文：方正仿宋简体
   一级标题：方正黑体简体，格式为“一、******”，单行不加句号
   二级标题：方正楷体简体（可加粗），格式为“（一）******”
   三级标题：方正仿宋简体加粗，格式为“一是******”，一般加句号
   所有标题均为三号字体
   ✅ 已搞定

4. 段落格式：
   对齐方式：两端对齐
   特殊格式：首行缩进 2 字符
   段前 / 段后：0 行
   行距：固定值 28 磅
   ✅ 已搞定

5. 页码：
   位置：页面底端
   对齐：居中
   ✅ 已搞定

6. 落款：
   日期：领导签批日期
   位置：最后一个字距离右侧 8 个字符（约 96 磅）
   单位名称：在日期上一行，较日期居中
   ✅ 已搞定

7. 字体统一：
   全文最后用 Times New Roman 字体
   刷一遍字母、数字、标点符号等
   ✅ 已搞定

🎉 所有格式项均已处理完成！
============================================================
"""

    # 插入文本并设置为只读
    text_area.insert(tk.END, format_text)
    text_area.configure(state='disabled')  # 只读

    # 等待用户关闭窗口
    guide_window.grab_set()  # 模态窗口（必须先关掉它才能操作其他窗口）
    guide_window.wait_window()

def OneKeyWord():
    global cn_num, num, punc, must
    cn_num = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
    num = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    punc = ["。", "，", "！", "？", "：", "；", "、", ".", "（", "）", "．"]
    must = ["要", "是", "能"]
    filecnt = 0


    # a = QApplication([''])
    # # time.sleep(1)
    # # 输出排版规则
    # print_format_guide()
    # print("请选择你需要处理的Word文件")
    # files, stylel = QFileDialog.getOpenFileNames(caption="多文件选择", directory="/", filter="Word 文档(*.docx)")




    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    print_format_guide()
    print("请选择你需要处理的Word文件")
    # 显示格式规范窗口
    show_format_guide()
    files = filedialog.askopenfilenames(
        title="多文件选择",
        initialdir="/",  # 可改为 os.path.expanduser("~") 打开用户目录
        filetypes=[("Word 文档", "*.docx")],
        parent=root
    )


    # 注意：files 是元组，转为列表方便处理
    files = list(files) if files else []
    print(files)  # 打印所选文件全部路径（包括文件名和后缀名）和文件类型

    for file in files:
        docx = Document(file)

        paragraphcnt = 0  # 段数计时器y
        filecnt = filecnt + 1
        print('这是第%s个文件：%s' % (filecnt, file))
        paragraphs = docx.paragraphs
        for paragraph in paragraphs:
            paragraphcnt = paragraphcnt + 1
            # remove_autonumber(paragraph)#去除所有的自动编码
            THandYXSJ(paragraph)  ## 将英文标点替换为中文标点，移除空格、制表符和换行符
            if paragraph.text == '':
                delete_paragraph(paragraph)
                paragraphcnt = paragraphcnt - 1
                continue
            print(f"'这是第 {paragraphcnt}段,{paragraph.text}")
            # print(paragraph.text)


            # --- 处理大标题 ---(9.1,16:17大标题排版格式完成）
            if paragraphcnt == 1 and len(paragraph.text) < 40:

                # 格式要求：方正小标宋简体、二号、加粗、居中、段前空一行、段后无额外间距

                # 在标题前添加一个空段落以实现“段前空一行”的效果
                # 1. 获取标题段落的 XML 元素
                p_element = paragraph._element
                # 2. 获取该元素的父级元素（通常是 <w:body> 或 <w:tc> 等）
                parent_element = p_element.getparent()
                # 3. 创建一个新的空段落 XML 元素 <w:p>
                #    使用从 docx.oxml 导入的 OxmlElement
                new_p_element = OxmlElement('w:p')
                # 4. 在父级元素中，将新段落插入到标题段落之前
                parent_element.insert(parent_element.index(p_element), new_p_element)

                # 设置标题段落的行距为固定值28磅（通常与二号字搭配）
                paragraph.paragraph_format.line_spacing = Pt(28)
                # 设置段后间距为0磅
                paragraph.paragraph_format.space_after = Pt(0)
                # （可选）明确设置段前间距为0磅（虽然主要由空行控制）
                # paragraph.paragraph_format.space_before = Pt(0)

                # 遍历并设置标题段落中所有 Run 的字体格式
                for run in paragraph.runs:
                    run.font.size = Pt(22)  # 二号字体大小
                    run.bold = True  # 加粗 （根据要求修正）
                    # 设置西文字体（如果标题中包含西文字符）
                    run.font.name = '方正小标宋简体'
                    # 关键：设置中文字体为 方正小标宋简体
                    # 使用从 docx.oxml.ns 导入的 qn 来处理命名空间
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '方正小标宋简体')

                # 设置段落居中对齐
                paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER

                # 跳过后续的处理步骤，因为标题格式已应用


            # --- 处理一级大标题 ---(9.1,16:20大标题排版格式完成）
            elif any(paragraph.text.startswith(prefix) for prefix in
                     ['一、', '二、', '三、', '四、', '五、', '六、', '七、', '八、', '九、', '十、']):
                print("识别到一级标题")
                paragraph.paragraph_format.line_spacing = Pt(28)  # 行距固定值28磅
                paragraph.paragraph_format.space_after = Pt(0)  # 段后间距=0
                for run in paragraph.runs:
                    run.font.size = Pt(16)  # 字体大小三号
                    run.bold = False  # 加粗
                    run.font.name = '楷体'  # 控制是西文时的字体
                    run.element.rPr.rFonts.set(qn('w:eastAsia'), '方正黑体简体')  # 控制是中文时的字体
                    paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT  # 居左
                continue


            # --- 识别二级标题 "(一) ..." (括号内为指定中文数字) ---
            # 注意这里是英文括号
            elif paragraph.text.startswith('（'):
                # 2. 查找 "）" 的位置
                end_bracket_pos = paragraph.text.find('）')
                # 3. 确保找到了 "）" 且它在合理的位置
                if 1 <= end_bracket_pos <= 5:
                    # # 4. 提取括号内的内容
                    # content_inside_brackets = paragraph.text[1:end_bracket_pos]
                    # # 5. 检查提取出的内容是否是中文数字 且 整个段落不以句号结尾
                    # if content_inside_brackets in ['一', '二', '三', '四', '五', '六', '七', '八', '九',
                    #                                '十'] and not paragraph.text.endswith('。'):
                    print(f"识别到二级标题: {paragraph.text}")
                    paragraph.paragraph_format.line_spacing = Pt(28)  # 行距固定值28磅
                    paragraph.paragraph_format.space_after = Pt(0)  # 段后间距=0
                    for run in paragraph.runs:
                        run.font.size = Pt(16)  # 字体大小三号
                        run.bold = False  # 加粗
                        run.font.name = '方正楷体简体'  # 控制是西文时的字体
                        run.element.rPr.rFonts.set(qn('w:eastAsia'), '方正楷体简体')  # 控制是中文时的字体
                        paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT  # 居zuo
                    continue



            # --- 识别三级标题 "以一是******”显示
            elif any(paragraph.text.startswith(prefix) for prefix in
                     ['一是', '二是', '三是', '四是', '五是', '六是', '七是', '八是', '九是', '十是']):
                print("识别到三级标题")
                paragraph.paragraph_format.line_spacing = Pt(28)  # 行距固定值28磅
                paragraph.paragraph_format.space_after = Pt(0)  # 段后间距=0
                for run in paragraph.runs:
                    run.font.size = Pt(16)  # 字体大小三号
                    run.bold = True  # 加粗
                    run.font.name = '方正仿宋简体'  # 控制是西文时的字体
                    run.element.rPr.rFonts.set(qn('w:eastAsia'), '方正仿宋简体')  # 控制是中文时的字体
                    paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT  # 居zuo
                continue


            # #处理正文
            else:
                # --- 设置段落格式 ---
                # 对齐方式：两端对齐
                paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY

                # 特殊格式：首行缩进，2字符
                # Word 中 1 个“字符”的宽度 ≈ 0.3528 mm 或 0.14 cm
                # 所以 2 字符 ≈ 0.7056 cm 或 0.28 英寸
                # 使用 Cm(0.7) 或 Inches(0.28) 是一个合理的近似
                paragraph.paragraph_format.first_line_indent = Cm(0.7)  # 近似 2 字符

                # 段前、段后间距：0行
                paragraph.paragraph_format.space_before = Pt(0)
                paragraph.paragraph_format.space_after = Pt(0)

                # 行距：固定值 28 磅
                paragraph.paragraph_format.line_spacing = Pt(28)
                paragraph.paragraph_format.line_spacing_rule = 3  # 3 对应 WD_LINE_SPACING.EXACTLY (固定值)

                # --- 设置字体格式 ---
                for run in paragraph.runs:
                    run.font.size = Pt(16)  # 16 磅 ≈ 3 号字
                    run.bold = False
                    run.font.name = '方正仿宋简体'  # 西文字体名（如果需要）
                    # 设置中文字体为 方正仿宋简体
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), '方正仿宋简体')

        # --- 设置页面边距 ---(页面设置实验成功9.1，16:01）
        setMargin(docx)
        print("已设置页面边距。")
        # --- 设置页脚居中 ---(页面设置实验成功9.1，23:01）
        add_page_number(docx)
        print("已设置页脚居中。")
        # --- 设置落款 ---(页面设置实验成功9.2，23:01）
        luokuan(docx)
        print("已设置落款（单位和日期）。")
        # --- 设置字母和数字字体 ---(页面设置实验成功9.2，23:01）
        ZST(docx)
        print("已设置落款（字母和数字字体）。")

        # 判断文件是否被其它程序占用锁定
        file_path = file
        # if is_file_locked(file_path):
        #     print(f"警告: 文件 '{file_path}' 可能正被另一个程序打开。请关闭该文件后再尝试操作。")
        #     # 可以在这里选择停止程序，例如:
        #     raise SystemExit("操作已取消。")
        # else:
        #     print(f"文件 '{file_path}' 似乎未被占用。")
        #     # 在这里执行需要写入文件的操作，例如:
        #     # doc.save(file_path)
        #     # print(f"文件已保存到 {file_path}")

        # 分离文件目录、文件名、扩展名

        directory, filename = os.path.split(file_path)
        name, ext = os.path.splitext(filename)
        suffix = "排版完成"
        # 构造新文件名：原名 + 后缀 + 扩展名
        new_filename = f"{name}{suffix}{ext}"

        # 构造新文件完整路径
        new_file_path = os.path.join(directory, new_filename)
        docx.save(new_file_path)
        print(f"保存地址{new_file_path}")
        # 处理完所有文件后
        messagebox.showinfo(f"完成", f"文件已排版完成！保存地址{new_file_path}")
    # 彻底关闭
    # tkinter
    # 主窗口
    root.quit()  # 退出主循环
    root.destroy()  # 销毁窗口资源



if __name__ == '__main__':
    OneKeyWord()
    #os.system("pause")
